from flask import Flask, send_file, jsonify, request
import os
import json
import subprocess
import threading
import time
import argparse
from utils.config import set_sdk_version
from core.BuildAndRun import clone_and_build
from core.ReadExcel import read_libraries_from_excel
from core.ReadExcel import get_repo_info

# 服务器配置
app = Flask(__name__)
HOST = '0.0.0.0'
PORT = 8888
BUFFER_SIZE = 4096
RESOURCE_DIR = os.path.abspath(os.path.join(os.getcwd(), "Libraries"))

# 全局变量，用于存储构建状态和结果
build_status = {}
build_results = {}

@app.route('/api/match', methods=['POST'])
def match_libraries():
    request_data = request.get_json()
    sdk_version = request_data.get('sdk_version')
    library_keyword = request_data.get('library_keyword')
    selected_indices = request_data.get('selected_indices', [])
    
    # 设置SDK版本
    set_sdk_version(sdk_version)
    
    # 从Excel读取库信息
    libraries, _, _ = read_libraries_from_excel()
    
    # 模糊匹配库名
    matched_libraries = []
    for lib in libraries:
        lib_name = lib['name'] if isinstance(lib, dict) and 'name' in lib else lib
        if isinstance(lib_name, str) and library_keyword.lower() in lib_name.lower():
            matched_libraries.append(lib)
    
    # 根据选择的索引获取库
    if selected_indices:
        selected_libraries = [matched_libraries[i] for i in selected_indices if 0 <= i < len(matched_libraries)]
    else:
        selected_libraries = matched_libraries
    
    # 返回匹配结果
    matched_names = [lib['name'] if isinstance(lib, dict) and 'name' in lib else lib for lib in matched_libraries]
    return jsonify({
        'status': 'matched',
        'matched_libraries': matched_names,
        'count': len(matched_libraries)
    })

@app.route('/api/build', methods=['POST'])
def build_har_files():
    request_data = request.get_json()
    selected_libraries = request_data.get('selected_libraries', [])
    sdk_version = request_data.get('sdk_version', '')
    
    if not selected_libraries:
        return jsonify({
            'status': 'error',
            'message': '未提供要构建的库'
        })
    
    # 生成唯一的构建ID
    build_id = str(int(time.time()))
    build_status[build_id] = 'running'
    build_results[build_id] = {
        'libraries': selected_libraries,
        'har_files': [],
        'errors': []
    }
    
    # 启动后台线程运行main.py
    thread = threading.Thread(
        target=run_main_script,
        args=(build_id, selected_libraries, sdk_version)
    )
    thread.daemon = True
    thread.start()
    
    # 立即返回构建ID，客户端可以用它来查询状态
    return jsonify({
        'status': 'started',
        'build_id': build_id,
        'message': f"开始构建 {len(selected_libraries)} 个库"
    })

def run_main_script(build_id, selected_libraries, sdk_version):
    """在后台运行main.py脚本构建HAR包"""
    try:
        # 设置SDK版本
        set_sdk_version(sdk_version)
        
        # 为每个库运行构建过程
        for lib in selected_libraries:
            try:
                # 提取库名
                lib_name = lib.get('name', str(lib)) if isinstance(lib, dict) else str(lib)
                print(f"开始构建库: {lib_name}")
                
                # 构建库
                clone_and_build(lib)
                
                # 查找生成的HAR文件
                har_files = []
                for root, dirs, files in os.walk(RESOURCE_DIR):
                    for file in files:
                        if file.endswith(".har"):
                            # 返回完整路径
                            har_files.append(os.path.join(root, file))
                
                # 添加到结果列表
                build_results[build_id]['har_files'].extend(har_files)
                print(f"库 {lib_name} 构建完成，找到 {len(har_files)} 个HAR文件")
                
            except Exception as e:
                error_msg = f"构建库 {str(lib)} 时出错: {str(e)}"
                print(error_msg)
                build_results[build_id]['errors'].append(error_msg)
        
        # 更新构建状态
        if build_results[build_id]['har_files']:
            build_status[build_id] = 'completed'
        else:
            build_status[build_id] = 'error'
            if not build_results[build_id]['errors']:
                build_results[build_id]['errors'].append('未生成任何HAR文件')
    
    except Exception as e:
        build_status[build_id] = 'error'
        build_results[build_id]['errors'].append(f"构建过程出错: {str(e)}")
        print(f"构建过程出错: {str(e)}")

@app.route('/api/build/status/<build_id>', methods=['GET'])
def check_build_status(build_id):
    """检查构建状态"""
    if build_id not in build_status:
        return jsonify({
            'status': 'error',
            'message': '构建ID不存在'
        }), 404
    
    status = build_status[build_id]
    result = {
        'status': status,
        'build_id': build_id
    }
    
    # 如果构建完成或出错，返回详细信息
    if status in ['completed', 'error']:
        result['har_files'] = build_results[build_id]['har_files']
        result['count'] = len(build_results[build_id]['har_files'])
        
        if status == 'error':
            result['errors'] = build_results[build_id]['errors']
    
    return jsonify(result)

@app.route('/download/<path:filepath>', methods=['GET'])
def download_file(filepath):
    """下载指定路径的文件"""
    # 处理相对路径和绝对路径
    if os.path.isabs(filepath):
        file_path = filepath
    else:
        file_path = os.path.join(RESOURCE_DIR, filepath)
    
    # 检查文件是否存在
    if not os.path.exists(file_path):
        return f"文件未找到: {filepath}", 404
    
    # 获取文件名
    filename = os.path.basename(file_path)
    
    # 参考resource.md中的方法，将文件传输到设备沙箱目录
    try:
        # 1. 读取文件内容
        with open(file_path, 'rb') as f:
            file_data = f.read()
        
        # 2. 获取沙箱目录路径
        dest_dir = os.path.join(os.path.dirname(file_path), 'sandbox')
        os.makedirs(dest_dir, exist_ok=True)
        
        # 3. 写入沙箱目录
        dest_path = os.path.join(dest_dir, filename)
        with open(dest_path, 'wb') as f:
            f.write(file_data)
        
        # 4. 校验文件完整性
        if os.path.getsize(dest_path) != os.path.getsize(file_path):
            os.remove(dest_path)
            return "文件传输失败", 500
        
        print(f"文件已成功传输到沙箱目录: {dest_path}")
        return send_file(file_path, as_attachment=True)
    except Exception as e:
        return f"文件传输错误: {str(e)}", 500

@app.route('/api/download/har/<build_id>', methods=['GET'])
def download_har_files(build_id):
    """获取指定构建ID的所有HAR文件列表"""
    if build_id not in build_status:
        return jsonify({
            'status': 'error',
            'message': '构建ID不存在'
        }), 404
    
    if build_status[build_id] != 'completed':
        return jsonify({
            'status': 'error',
            'message': f"构建尚未完成，当前状态: {build_status[build_id]}"
        })
    
    har_files = build_results[build_id]['har_files']
    if not har_files:
        return jsonify({
            'status': 'error',
            'message': '没有可下载的HAR文件'
        })
    
    # 返回文件列表，包含下载链接
    download_links = []
    for file_path in har_files:
        filename = os.path.basename(file_path)
        download_links.append({
            'filename': filename,
            'path': file_path,
            'download_url': f"/download/{file_path}"
        })
    
    return jsonify({
        'status': 'success',
        'har_files': download_links,
        'count': len(download_links)
    })

if __name__ == "__main__":
    app.run(host=HOST, port=PORT, debug=True)